Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3주차 리뷰 부탁드립니다. #11

Merged
merged 33 commits into from
Sep 22, 2024
Merged

3주차 리뷰 부탁드립니다. #11

merged 33 commits into from
Sep 22, 2024

Conversation

sunandrabbit
Copy link
Contributor

week3 궁금한점 (리뷰 부탁드립니다.)

  • 팀원마다 코드스타일이 다른경우 통일을 하나요?
  • 프로젝트 시작 시 세팅은 어느정도로 하나요?
  • 현재 팀원마다 각각 domain을 1개씩 담당하여 작업을 하고 있습니다. 이러한 경우 다른 팀원이 만들어야 하는 객체를 참조해야 되는 상황일 때,(저는 그냥 구현을 해버려서 conflict가 발생했습니다.) 구현을하지 않고 mock 혹은 fake 객체를 만들어 두고 작업을 하는 편인가요?
  • 보통 이 정도 규모의 프로젝트를 분업하게 되면 어떠한 기준으로 작업을 분배하나요?
  • conflict resolve시의 기준이 있나요?

suno-boy and others added 30 commits September 18, 2024 20:38
week3 인증관련 구현 사항
Week3 프로젝트 관련 구현사항
@yoo-jaein yoo-jaein self-requested a review September 21, 2024 07:21
Copy link

@yoo-jaein yoo-jaein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3주차 고생 많으셨습니다!
리드미에 역할과 작업 내역을 꼼꼼히 작성해주셔서 잘 읽었습니다.

혹시 서비스의 구체적인 기획서가 있다면 공유해주세요.
프로젝트 리뷰에 참고하겠습니다 :)

- style : 코드 스타일 변경 (포매팅 수정, 세미콜론 추가 등)
- refactor : 코드 리팩토링
- test : 테스트 코드 추가, 수정
- chore : 빌드 프로세스, 도구 설정 변경 등 기타 작업

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

- style : 코드 스타일 변경 (포매팅 수정, 세미콜론 추가 등)
- refactor : 코드 리팩토링
- test : 테스트 코드 추가, 수정
- chore : 빌드 프로세스, 도구 설정 변경 등 기타 작업

---

# 구현 기능 목록

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// OAuth2에서 가져온 유저 정보
public static class OAuthAttributes {

private Map<String, Object> attributes;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Map<String, Object>로 두는 것은 좋지 않습니다.
특히 Object를 사용하면 타입 체크가 컴파일 시점에 이루어지지 않아 버그를 발생시킬 수 있습니다.
가능하다면 명시적인 필드를 가진 클래스를 사용하는 것이 어떨까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/core/OAuth2AuthenticatedPrincipal.html

oauth로 부터 .getAttributes()를 받아오기 때문에 데이터 타입을 유지해야 합니다.
인증 플랫폼마다 반환되는 결과가 달라서 각자 값만 받아오기도 어렵습니다.

@@ -0,0 +1,117 @@
package com.example.team1_be.DTO;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바 패키지 이름 규칙에 따르면 언더스코어(_) 대신 카멜 케이스를 사용하는 것이 좋아요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

패키지명 수정하겠습니다.

// OAuth2User 반환용
public record PrincipalDetails(
UserEntity user,
Map<String, Object> attributes,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 Map<String, Object>가 사용되었네요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상동

}

@Transactional
protected UserEntity saveOrUpdate(OAuthAttributes attributes) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동일 클래스 내에서 사용하는 경우 private으로 선언하는 것이 좋습니다

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.spring.io/spring-framework/reference/data-access/transaction.html

@transactional이 private면 프록시 객체 메소드를 실행할 수 없어서 protected로 했습니다.


public Project updateProject(long get, ProjectDTO.update update) {
Project project = projectRepository.findById(get)
.orElseThrow(() -> new BaseHandler(HttpStatus.NOT_FOUND, "존재하지 않음"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

에러 메시지는 "프로젝트가 존재하지 않음"과 같이 구체적으로 설명하는 것이 좋습니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영하겠씁니다.

return project.getGuests();
}

public Project createProject(ProjectDTO.create create) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Transactional 어노테이션을 활용하면 좋겠습니다!
(createProject 외에도 많은 변경, 생성이 일어나는 메서드)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Transactional은 보통 Service Layer에서만 적용을 하면 되나요? 제가 알기로는 JpaRepository는 @Transactional를 포함하고 있고, Controller의 경우 데이터 변환이 일어나지 않기 때문에 위와 같이 생각했습니다. 멘토님은 어떠신가요?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Transactional은 보통 Service 계층에 적용합니다. (repository, controller 모두 말씀해주신 부분이 맞습니다.)

project.setGuests(update.getGuests());
project.setOptions(update.getOptions());
project.setStartDate(update.getStartDate());
project.setEndDate(update.getEndDate());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여러 번의 set 호출 대신 더 나은 방법을 고민해보시면 좋을 것 같아요.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update의 경우 기존의 Entity를 id로 조회하여 가져오고. 해당 Entity의 몇몇 field의 정보를 변경하는 것이라서 이렇게 구현을 했습니다. 멘토님의 말을 듣고 생각해보니 ProjectEntity에 void updateProject()라는 메소드를 만들어 생성자 초기화하듯이 업데이트를 구현할 수도 있을거 같네요 멘토님은 어떠하신가요?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여러 번의 setter 호출 대신, 엔티티에 update를 위한 메서드를 만들어서 사용하는 것이 좋습니다.

  1. 여러 setter를 사용하면 객체가 일관성 없는 상태로 사용될 위험이 있습니다.
    예를 들어, 지금 updateProject() 내에서 set, set, set으로 정보를 변경하는 로직을 짰는데
    이후 Project 객체에 새로운 필드가 추가되면서 해당 필드에 대한 set을 누락할 가능성이 있습니다.
    새로운 필드가 여러 개라면 더욱 누락할 위험이 높아요.

  2. 객체 지향 원칙에 위배됩니다.
    외부에서 직접 객체 내부 상태를 (setter로) 변경할 수 있게 되면서 캡슐화가 약해집니다.

추가로 이 메서드에 @Transactional을 추가하면 Jpa 변경 감지 기능 덕분에 엔티티의 변경사항이 자동으로 데이터베이스에 반영되어 아래 save 메서드를 호출할 필요가 없습니다.

import org.springframework.stereotype.Component;

@Component
public class UserMapper {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@yoo-jaein
Copy link

팀원마다 코드스타일이 다른경우 통일을 하나요?

  • 네 통일합니다. 보통 팀 전체에 적용하는 코드 스타일이 있습니다.

프로젝트 시작 시 세팅은 어느정도로 하나요?

  • 기본적인 스프링 라이브러리 의존성 세팅, 데이터베이스 연결, 핵심 도메인 설계 정도 진행합니다.

현재 팀원마다 각각 domain을 1개씩 담당하여 작업을 하고 있습니다. 이러한 경우 다른 팀원이 만들어야 하는 객체를 참조해야 되는 상황일 때,(저는 그냥 구현을 해버려서 conflict가 발생했습니다.) 구현을하지 않고 mock 혹은 fake 객체를 만들어 두고 작업을 하는 편인가요?

  • 도메인 간에도 연관관계가 있기 때문에 동시에 서로 다른 도메인을 작업하는 경우 충돌이 발생할 위험이 높습니다. 그래서 가장 중요한, 핵심이 되는 도메인은 페어코딩해서 같이 커밋하고 그 이후로 나눠져서 작업하는 편입니다. Mock, fake 객체를 만든다면 이후 변경될 가능성이 매우 높고 충돌 해소를 위해 두번, 세번 추가 작업할 가능성이 높기 때문에 처음부터 페어코딩하고 각자 작업하러 들어가곤 합니다.

보통 이 정도 규모의 프로젝트를 분업하게 되면 어떠한 기준으로 작업을 분배하나요?

  • 어느정도의 규모인지 명확하지 않은데, 가능하면 충돌이 발생하지 않도록 feature를 잘게 분리한 다음 작업을 분배합니다. (선호도, 난이도를 고려)

conflict resolve시의 기준이 있나요?

  • 이미 커밋된 로직을 이어가되, 동일한 파일에서 충돌이 일어나는 경우 페어코딩하는 것 처럼 작업자를 불러 같이 수정합니다.

Copy link

@yoo-jaein yoo-jaein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원활한 진행을 위해 우선 Approve하겠습니다.
이번 주 신규 작업과 함께 개선 부탁드립니다! 😀

@yoo-jaein yoo-jaein merged commit db5f7a0 into review Sep 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants